﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using LiveChartsCore;
using LiveChartsCore.Defaults;
using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.SkiaSharpView.Painting;
using MeterReader.Common.Extensions;
using MeterReader.PubSubEvents;
using MeterReader.Services.Repositories;
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using SkiaSharp;

namespace MeterReader.ViewModels
{
    public class HistoryViewModel : BindableBase
    {
        private readonly IEventAggregator _eventAggregator;
        private readonly IWriteDbRepository _writeDbRepository;
        private ObservableCollection<DateTimePoint> _dateTimePoints = new();

        public HistoryViewModel(IEventAggregator eventAggregator, IWriteDbRepository writeDbRepository)
        {
            _eventAggregator = eventAggregator;
            _writeDbRepository = writeDbRepository;
            LiveCharts.Configure(config => config.HasGlobalSKTypeface(SKFontManager.Default.MatchCharacter('汉')));
            Series[0].Values = _dateTimePoints;
            ComBoxSource = _writeDbRepository.GetMeterColumnsFromTMeters().ToList();
            GoBackDataMonitorCommand = new DelegateCommand<string>(GoBackDataMonitor);
            SearchHistoryCommand = new DelegateCommand(SearchHistory, () => EndDateTime > BeginDateTime).ObservesProperty(() => BeginDateTime).ObservesProperty(() => EndDateTime);
        }

        #region properties

        public DelegateCommand<string> GoBackDataMonitorCommand { get; set; }
        public DelegateCommand SearchHistoryCommand { get; set; }

        public Axis[] XAxes { get; set; } =
            {
                new DateTimeAxis(TimeSpan.FromHours(1), date => date.ToString("yyyy-MM-dd HH:mm:ss"))
                {
                    NameTextSize = 15,
                    LabelsRotation = 15,
                    NamePaint = new SolidColorPaint(SKColors.WhiteSmoke),
                    LabelsPaint = new SolidColorPaint(SKColors.DarkGray),
                    TextSize = 15,
                    SeparatorsPaint = new SolidColorPaint(SKColors.LightSlateGray) { StrokeThickness = 2 },
                }
            };

        public Axis[] YAxes { get; set; } =
            {
                new Axis()
                {
                    Name = "总功率(Kw.h)",
                    NameTextSize = 15,
                    NamePaint = new SolidColorPaint(SKColors.WhiteSmoke),
                    LabelsPaint = new SolidColorPaint(SKColors.DarkGray),
                    TextSize = 15,
                    MinLimit = 0,
                    SeparatorsPaint = new SolidColorPaint(SKColors.LightSlateGray) { StrokeThickness = 2 },
                    Labeler = v => $"{v}(Kw.h)"
                }
            };

        public ObservableCollection<ISeries> Series { get; set; } =
            new()
            {
                new LineSeries<DateTimePoint>()
                {
                    Fill = null,
                    GeometrySize = 0,
                    LineSmoothness = 1,
                }
            };

        private DateTime _beginDateTime = DateTime.Now;

        public DateTime BeginDateTime
        {
            get { return _beginDateTime; }
            set { SetProperty(ref _beginDateTime, value); }
        }

        private DateTime _endDateTime = DateTime.Now;

        public DateTime EndDateTime
        {
            get { return _endDateTime; }
            set { SetProperty(ref _endDateTime, value); }
        }

        private List<string> _comBoxSource = new List<string>();

        public List<string> ComBoxSource
        {
            get { return _comBoxSource; }
            set { SetProperty(ref _comBoxSource, value); }
        }

        private string _comBoxSelectedItem = "Col1";

        public string ComBoxSelectedItem
        {
            get { return _comBoxSelectedItem; }
            set { SetProperty(ref _comBoxSelectedItem, value); }
        }

        #endregion properties

        private void GoBackDataMonitor(string obj) => _eventAggregator.GetEvent<NavigateEvent>().Publish(obj);

        private void SearchHistory()
        {
            var query = _writeDbRepository.SearchHistory(t => t.Date >= BeginDateTime && t.Date <= EndDateTime);
            if (query.Any())
            {
                var dateTimePoints = query.Select(t => new DateTimePoint(t.Date!, t.GetProperty(ComBoxSelectedItem)));

                if (dateTimePoints.Any())
                {
                    _dateTimePoints!.Clear();
                    foreach (var item in dateTimePoints)
                    {
                        _dateTimePoints!.Add(item);
                    }
                }
            }
        }
    }
}
